//
//  ViewController.swift
//  MZTool
//
//  Created by ayi on 01/25/2022.
//  Copyright (c) 2022 ayi. All rights reserved.
//

import UIKit
import MZTool
//import ZegoExpressEngine

class ViewController: BaseViewVCtrl {
    
    var observe: NSKeyValueObservation?
    var timer1: MZTimer?
    var timer2: MZTimer?
    var coder: MZRecorder?
    var player: MZAudioPlayer?
    var player2: MZAudioPlayer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        self.mz_prefersNavigationBarHidden = true
        //MARK:
        UIFont.mz.size(13, auto: false)
        "123".mz.isPureInt()
        "1232312".mz.isPureInt()
        let textView: UITextView = UITextView.init()
        textView .snapshotView(afterScreenUpdates: false)
        textView.mz.left = 111

        addNotifications()
        
        do{
            let imgv = UIImageView.init(image: UIImage.mz.QR.img(qrContent: "12312312313213", qrSize: CGSize(width: 100, height: 100), nil))
            imgv.frame = CGRect(x: 0, y: 100, width: 100, height: 100)
            self.view.addSubview(imgv)
            imgv.isUserInteractionEnabled = true
            imgv.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(gototest)))
        }
        do{
            let imgv = UIImageView.init()
            imgv.frame = CGRect(x: 200, y: 100, width: 100, height: 100)
            imgv.layer.addSublayer(CALayer.mz.create_GradientLayer(imgv.mz.size, (CGPoint(x: 0, y: 0.5), CGPoint(x: 1, y: 0.5),
                                                                                  [UIColor.white, UIColor.black, UIColor.red],
                                                                                  [NSNumber.init(value: 0.0), NSNumber.init(value: 0.5), NSNumber.init(value: 1.0)])))
            self.view.addSubview(imgv)
            imgv.isUserInteractionEnabled = true
            imgv.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(gototest3)))
        }
        do{
            let imgv = UIImageView.init()
            imgv.frame = CGRect(x: 200, y: 230, width: 100, height: 10)
            imgv.layer.addSublayer(CALayer.mz.create_CAShapLayer(imgv.bounds, (UIColor.white, 10, 3)))
            self.view.addSubview(imgv)
        }
        do{
            let imgv = UIImageView.init()
            imgv.frame = CGRect(x: 20, y: 230, width: 100, height: 100)
            imgv.image = UIImage.mz.create_Gradient(imgv.mz.size, (CGPoint(x: 0, y: 50), CGPoint(x: 100, y: 50),
                                                                   [UIColor.white, UIColor.black, UIColor.red],
                                                                   [0.0, 0.5, 1.0]))
            self.view.addSubview(imgv)
        }
        // Do any additional setup after loading the view, typically from a nib.
        let mode = TestModel.init()
//        mode.setValue(nil, forKey: "app1")
//        self.observe = mode.observe(\.app) { vv in
//            print(vv)
//        }
//        self.observe = mode.observe(\.app, options: [.new]) { t, tt in
//            print(tt)
//        }
        DispatchQueue.main.mz.after(time: 3) {
            mode.app = 1
        }
        print(TestModel.isKind(of: TestModel.classForCoder()))
//        print(mode.value(forKey: "app") as Any)
//        mode.value(forKey: "names")
//        print(mode.value(forKey: "names"))
//        mode.kkkkkk = ""
//        print(mode.kkkkkk ?? "")
//        let a = NMQRCodePreviewView.init(frame: CGRect.zero, CGRect.zero, UIColor.red)
//        print(MZ.gainIvarNames(objc: a.classForCoder))
//        print(MZ.gainPropertyNames(objc: a.classForCoder))
//        print(MZ.gainMethodNames(objc: UIView.classForCoder()))
        
//        let a = DispatchQueue.init(label: "1213123123")
//        let a = DispatchQueue.init(label: "1213123123", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
//        a.async {
//            print("out-------")
//            a.sync {
//                print("in-------")
//            }
//            a.async {
//                print("in-------2")
//            }
//            a.sync {
//                print("in-------3")
//            }
//            a.async {
//                print("in-------4")
//            }
//            a.async {
//                print("in-------5")
//            }
//            a.async {
//                print("in-------6")
//            }
//        }
//        let ddd = DispatchSemaphore.init(value: 1)
//        let opq = OperationQueue.init()
//        opq.maxConcurrentOperationCount = 2
//        let op = BlockOperation.init {
//            ddd.wait()
//            DispatchQueue.main.after(time: 3) {
//                print("op1 ---- 1-1")
//                ddd.signal()
//            }
//            print("op1 ---- 1")
//        }
//        op.addExecutionBlock {
//            print("op1 ---- 2")
//        }
//        let op2 = BlockOperation.init {
//            ddd.wait()
//            print("op2 ---- 1")
//            ddd.signal()
//        }
//        op2.addDependency(op)
//        opq.addOperation(op)
//        opq.addOperation(op2)
        
//        var ptmutex = pthread_mutex_t()
//        var atter = pthread_mutexattr_t()
//        pthread_mutexattr_init(&atter)
//        pthread_mutexattr_settype(&atter, PTHREAD_MUTEX_DEFAULT)
//        pthread_mutex_init(&ptmutex, &atter)
        
        
        let group = DispatchGroup.init()
        let ddd = DispatchSemaphore.init(value: 3)
        let qq = DispatchQueue.init(label: "1213123123", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
        group.enter()
        qq.async(group: group, execute: DispatchWorkItem(block: {
//            DispatchQueue.main.after(time: 3) {
//                print("1111111")
//                group.leave()
//            }
        }))
        group.enter()
        qq.async(group: group, execute: DispatchWorkItem(block: {
//            DispatchQueue.main.after(time: 3) {
//                print("222222")
//                group.leave()
//            }
        }))
        group.enter()
        qq.async(group: group, execute: DispatchWorkItem(block: {
//            DispatchQueue.main.after(time: 5) {
//                print("33333")
//                group.leave()
//            }
            DispatchQueue.main.asyncAfter(deadline: 3) {

            }
        }))
        group.enter()
        qq.async(group: group, execute: DispatchWorkItem(block: {
            print("1111111")
            group.leave()
        }))
        group.notify(queue: qq, work: DispatchWorkItem(block: {
            print("ffff")
        }))
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        if let p = player, p.isPlaying {
            p.playDone()
        }
        if let p = player2, p.isPlaying {
            p.playDone()
        }
    }
    
    func addNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground(notification:)), name: UIApplication.didEnterBackgroundNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterForeground(notification:)), name: UIApplication.willEnterForegroundNotification, object: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    @objc func gototest() {
//        self.navigationController?.pushViewController(TestViewController.init(), animated: true)
        
//        let alert = MZAlertViewController.init(title: "111", message: "111222")
//        let ac1 = MZAlertAction.init(title:"放假啦") { action in
//
//        }
//        let ac2 = MZAlertAction.init(title: "hehehhe") { action in
//
//        }
//        alert.addAction(ac1)
//        alert.addAction(ac2)
//        DispatchQueue.main.async {
//            self.present(alert, animated: true)
//        }
        let url = try! FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("111.m4a")
        self.player = MZAudioPlayer(url: url, update: { time in
            guard let t = time else{return}
            print("player \(t)")
        })
        self.player?.togglePlay()
    }
    
    @objc func gototest2() {
        let alert = UIAlertController.init(title: "123123213213", message: "3123213123", preferredStyle: UIAlertController.Style.alert)
        let ac1 = UIAlertAction.init(title: "1111111", style: .cancel)
        let ac2 = UIAlertAction.init(title: "2222222s", style: .default)
        alert.addAction(ac1)
        alert.addAction(ac2)
        DispatchQueue.main.async {
            self.present(alert, animated: true)
        }
    }
    
    @objc func gototest3() {
        let url = try! FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("111.m4a")
        coder = MZRecorder.init(url: url) { time in
            guard let t = time else{return}
            print("recorder \(t)")
        }
        DispatchQueue.main.mz.after(time: 5) {
            self.coder?.stop()
            print(url)
        }
        
//        let url = try! FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("111.m4a")
//            player2 = MZAudioPlayer(url: url, update: { time in
//            guard let t = time else{return}
//            print("player2 \(t)")
//        })
//        player2?.togglePlay()
    }
    
    
    //TODO: 进入后台
    @objc func applicationDidEnterBackground(notification: Notification){
        if let p = player, p.isPlaying {
            p.playDone()
        }
        if let p = player2, p.isPlaying {
            p.playDone()
        }
    }
    
    //TODO: 即将进入前台
    @objc func applicationWillEnterForeground(notification: Notification){
        
    }
    
    
    deinit {
        
    }
}












class TestModel : NSObject {
    @objc var name : String = ""
    @objc var app : Int = 0
    
    func aaa() {
        
    }
    
//    override class var accessInstanceVariablesDirectly: Bool{
//        return false
//    }
//
//    override class func value(forUndefinedKey key: String) -> Any? {
//        print("qqq"+key)
//        return nil
//    }
//
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
        print("www")
    }
    
    override class func setNilValueForKey(_ key: String) {
        print("222222222-----" + key)
    }
    
//    override class func automaticallyNotifiesObservers(forKey key: String) -> Bool {
//        return false
//    }
    
}

extension TestModel {
    private struct pKeys {
        static var kkkk = "123213"
    }
    
    @objc public var kkkkkk: String?{
        get{objc_getAssociatedObject(self, &pKeys.kkkk) as? String}
        set{objc_setAssociatedObject(self, &pKeys.kkkk, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)}
    }
    
}
